home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-20
/
rs0422.zip
/
ROSEZSW
/
PATHS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-26
|
10KB
|
303 lines
/*
* Copyright 1988 by the Radio Amateur Telecommunications Society
* and Thomas A. Moulton, W2VY
*
* This software may only be modified, copied, distributed or
* executed for non-profit purposes by individuals operating
* systems in the Amateur Radio Service. Credit to the
* author(s) and to the Radio Amateur Telecommunications Society
* must be made in modules where RATS provided software is used,
* and in any announcements and documentation.
*
* As a non-profit, research and development organization, the
* Radio Amateur Telecommunications Society distributes software
* in both executable and source forms. This policy is in place
* to encourage the development and distribution of OSI-based,
* networking tools. In order to protect the interests of the
* Society and the authors, we have placed some conditions
* of use on the software. Other groups are encouraged
* to place the same or similar guidelines on
* software they produce.
*
* The Radio Amateur Telecommunications Society reserves the right
* to specify and alter the terms under which software provided by
* the Society may be used. This policy is consistent with the
* objective of uniform and consistent "Open Systems Interconnections."
*
* All acceptable Amateur Radio related uses of this software
* will be outlined in the "ROSE Implementer's Guide". Individuals
* or organizations wishing to add to, or modify the provisions of
* the guide to accommodate local or evolutionary requirements
* should document the proposed change(s) and forward them to the
* Society. If accepted, written notification will be provided by
* the Society to the submitting organization or individual(s).
* The Society will then issue a "ROSE Implementer's Guide Change
* Notice". Periodically, the Society will re-issue the "ROSE
* Implementer's Guide" and incorporate the text of the change
* notices. This procedure has been put in to place to ensure
* compatibility between systems and to ensure their "Openness"
* and interoperability.
*
* No part of this software may be used in other packages
* without prior authorization from the author or the Society.
* Software incorporating this module, all or in part, must be
* provided to the Society prior to distribution or use by
* anyone not directly involved in testing of the revised
* environment. Current releases of the combined software must
* be provided to the Society in both source and executable
* forms. Adequate documention to produce an executable module
* from the provided source must also be included.
*
* Non-Amateur Radio non-profit uses may be authorized on a case
* by case basis. Inquiries for such use may be made in writing
* to the Society. Non-commercial uses consistent with the
* general principles of Open Systems Interconnection Reference
* Model will be generally considered with favor.
*
* Commercial licensing of the software is also available based
* on normal commercial terms. Licensing inquiries should be
* directed to the Society. Commercial licensing of the standard
* software will be done in situations which materially benefit
* the Amateur Radio Packet Network. Additional licensing is
* reserved by the individual authors.
*
* The Radio Amateur Telecommunications Society provides this software
* on an "as is" basis. The Society assumes no liability for
* loss incurred through the use of this software. Amateur Radio
* use of this software implies non-commercial and voluntary
* development, deployment and use of this software in a "Amateur",
* non-commercial service. Commercial users are encouraged to
* inspect their copies of the source code. Source code modification
* licenses are available if a combined Object and Source Code
* license was not originally established.
*
* The Society may be contacted by writing or calling at:
*
* The Radio Amateur Telecommunications Society
* 206 North Vivyen Street.
* Bergenfield, New Jersey 07621
*
* Telephone: 201-387-8896
*
*/
#include "data.h"
#include "buffer.h"
#include "ax25.h"
#include "ax25l2.h"
#include "l3struc.h"
#include "x25cause.h"
#include "l3calls.h"
extern int L3TRIED[];
struct axcb *linked_to(), *NET_CONN();
/* This file has the routins that are used by Call Setup to find
a path for the user's call request. THEY ARE ONLY USED FOR NETWORK LINKS!
The only static data structure is a pointer to the pending call list,
everything else is stored in the VCS struc for the pending call.
VCS->next Next vcs in pending chain
VCS->peer The vcs that caused the call (the calling vc)
VCS->tx_queue char pointer to the routing table entry
VCS->alt Used as index into routing alternatives
A link will be tried if the L3TRIED[] entry is zero
When a node link comes up the pending calls will be checked
to see if it can satisfy the call and it is a higher priority
than the alternative that the call is currently waiting on
The peer (VCS->peer) is fully linked and totally valid, and should
be in P3
*/
struct VCS *pending_calls;
find_path(vc)
register struct VCS *vc;
{ /* Input a VC in pending call format
but ONLY pointed to by it's peer!
Output TRUE - call routed, or put back in queue
FALSE - Failed, check vc->alt
If alt = 255 then no more routes
else no free memory for the link */
static char i, j;
static unsigned char *altlist;
static struct axcb *axcb;
if (vc->alt == 255) j = 0; /* First Time */
else /* Try next link */ {
j = vc->alt & 0x0f; /* Alt recs and L3CALL Network links */
vc->alt = 255; /* only range from 0-15 */
}
altlist = (unsigned char *)vc->tx_queue;
while (j < (altlist[0]>>4) & 0x0f) {
i = altlist[++j];
if ((i == 0) || (i > 15)) break; /* Wierd entry */
if (! L3TRIED[i] ) /* Hasn't been tried in a while */ {
vc->alt = j;
if (linked_to(&L3CALL[i],&L3CALL[0],&axcb)) /*Link exists*/ {
if (axcb->R == R1) /* Link Ready!! */ {
vc->parent = axcb;
vc->tx_queue=NULL;
vc->WI = L3_WI[i];
set_p(vc,P2,0);
return TRUE;
}
else /* Link Not ready */ {
vc->next=pending_calls;
pending_calls=vc; /* Wait for R1 */
return TRUE;
}
}
else /* Link does not exist */ {
if (!(axcb=NET_CONN(i))) return FALSE;
axcb->link_num=i;
vc->next=pending_calls;
pending_calls=vc; /* Wait for R1 */
return TRUE;
}
}
}
return FALSE;
}
route_fail(sx) /* Attempt next alternative for pending calls waiting for path */
char sx; /* This is ONLY called from l3_st_up, disconnected */
{
register struct VCS *vc;
static struct VCS *vc1;
static unsigned int cause;
static unsigned char s;
if (!(s=sx)) return; /* Not a network link */
vc=pending_calls;
if (!vc) /* No pending calls */ return;
pending_calls=vc->next;
vc->next=NULL;
vc1=NULL;
while (vc) /* More calls to process */ {
if (s == *((char *) vc->tx_queue + vc->alt)) {
/* Failed with calls pending */
L3TRIED[s]=L3DELAY[s];
if (!find_path(vc)) /* Failed, Why? */ {
if (vc->alt == 255)/* No alternatives left */ {
cause=Out_of_Order;
}
else /* No memory */ {
cause=Congestion+120;
}
vc_clear(vc, cause);
}
else { /* Find_Path put it back on list,*/
/* no longer working on root */
/* Or the call is now in P2 */
if ( !vc1 && (vc == pending_calls) ) vc1=vc;
}
}
else /* Not working on this link */ {
vc->next=pending_calls; /* Re-queue this guy */
pending_calls=vc;
if (!vc1) /* Is null, was working on root */ vc1=vc;
}
if (vc1) /* Not working on the root of the list */ {
vc=vc1->next;
if (vc) /* Insure it's not NULL */ {
vc1->next=vc->next;
vc->next=NULL;
}
}
else /* Need to extract the first item */ {
vc=pending_calls;
if (vc) /* Not NULL */ {
pending_calls=vc->next;
vc->next=NULL;
}
}
}
return;
}
route_success(lnk) /* Process calls that can use the link that is now in R1 */
struct axcb *lnk; /* Will process all calls that have tried or are trying */
{ /* This link */
register struct VCS *vc;
static struct VCS *vc1;
static unsigned char i,s;
if (!(s=lnk->link_num)) return; /* Not a network link */
/* find_call(&lnk->path[0]); /* First call is destination */
/* if (s<1 || s>15) return; /* Not a network link */
L3TRIED[s] = 0; /* Link is up, allow calls */
lnk->maxvc = L3_MAXVC[s];
vc=pending_calls;
vc1=NULL;
while (vc) /* More calls to check */ {
for (i=1; i <= vc->alt; i++) {
if (s == *(( (char *) vc->tx_queue) + i)) {
/* vc's link is finally in R1 !! */
if (vc1==NULL) /* Remove first vc */
pending_calls=vc->next;
else /* have others before me */
vc1->next=vc->next;
vc->next=NULL;
vc->tx_queue=NULL;
vc->parent=lnk;
vc->WI = L3_WI[s];
set_p(vc,P2,0);
i=0; /* We removed vc, vc1 is ok */
break; /* Exit the for loop */
}
} /* End of the for loop */
if (i) /* the entry was not removed, advance vc1 */
if (vc1) /* Not Null */ vc1=vc1->next;
else /* Was working on root */ vc1=pending_calls;
if (vc1) /* There is a previous pending call */ vc=vc1->next;
else /* Still working on root */ vc=pending_calls;
} /* End of While loop */
}
extern unsigned char RTable[];
extern unsigned char NPAroute[][16];
int check_x121();
find_route(ptr,x121)
unsigned char **ptr;
unsigned char x121[];
{
static unsigned char i, lensv;
static int l, r, disp;
register unsigned char *ch;
ch = RTable; /* Routing Table Root */
lensv = x121[0] & 0x0f;
i = 0; /* Start with first digit of DNIC */
r = -1;
do {
if (*ch != 0) r = *(ch+1);
if (*ch == 2) /* Modify Address and return */ {
adr_copy(0,NPAroute[r],0, x121); /* New Called */
return -1; /* need to re-route call */
}
if (i == lensv) break;
l = x121[ (i>>1) +1 ];
if (!(i&1)) /* High */ l = l>>4;
i++;
disp = *(ch+2+(l&0x0f));
ch += (disp*12); /* Advance to next record */
} while (disp != 0);
if (r == -1) return 0; /* No known route */
*ptr = &NPAroute[r][0];
return 1;
}